﻿using Microsoft.AspNetCore.Mvc;
using UpperComputer.Application;
using UpperComputer.Web.Entry.Models;
using YFurion.Application;
using YFurion.Attributes;

namespace UpperComputer.Web.Entry.Controllers
{
    /// <summary>
    /// 主控制器
    /// </summary>
    [OnlyCheckLogin]
    [ApiDescriptionSettings(ApiGroupConst.DEFAULT)]
    public class MainController : AuthorizeController
    {
        private readonly IBaseUserService _userService;
        private readonly IBaseMenuService _menuService;
        private readonly IBaseRolePermissionService _rolePermissionService;
        /// <summary>
        /// 主控制器构造函数
        /// </summary>
        /// <param name="userService">用户服务</param>
        /// <param name="menuService">菜单服务</param>
        /// <param name="rolePermissionService">角色权限服务</param>
        public MainController(
            IBaseUserService userService,
            IBaseMenuService menuService,
            IBaseRolePermissionService rolePermissionService)
        {
            _userService = userService;
            _menuService = menuService;
            _rolePermissionService = rolePermissionService;
        }

        /// <summary>
        /// 获取用户信息及权限
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<MainOutputModel> Get()
        {
            MainOutputModel mainOutputModel = new MainOutputModel();
            mainOutputModel.UserResultDto = await _userService.GetCacheById(YSession.SubjectId);
            BaseMenuResultRequestDto menuInput = new BaseMenuResultRequestDto()
            {
                IsActive = true,
                CanSearchMenuButtons = true,
            };
            List<BaseMenuResultDto> menuDtos = await _menuService.GetMenus(menuInput);
            if (YSession.Account != SA)
            {
                string[] roleCodes = await _userService.GetRoleCodesCache(mainOutputModel.UserResultDto);
                BaseRolePermissionResultRequestDto rolePermissionResultRequestDto = new BaseRolePermissionResultRequestDto
                {
                    RoleCodes = roleCodes
                };
                PagedResultDto<BaseRolePermissionDto> rolePermissionPagedResultDto =
                await _rolePermissionService.GetAll(rolePermissionResultRequestDto);
                GetPermissions(menuDtos, rolePermissionPagedResultDto.Items);
            }
            mainOutputModel.MenuResultDtos = menuDtos;
            return mainOutputModel;
        }

        /// <summary>
        /// 获取权限
        /// </summary>
        /// <param name="menuDtos"></param>
        /// <param name="rolePermissionDtos"></param>
        private void GetPermissions(ICollection<BaseMenuResultDto> menuDtos, IReadOnlyList<BaseRolePermissionDto> rolePermissionDtos)
        {
            for (int i = 0; i < menuDtos.Count; i++)
            {
                BaseMenuResultDto menuDto = menuDtos.ElementAt(i);
                if (menuDto.Childrens?.Count > 0)
                {
                    GetPermissions(menuDto.Childrens, rolePermissionDtos);
                }

                bool hasMenu = false;
                foreach (BaseRolePermissionDto item1 in rolePermissionDtos)
                {
                    if (item1.PermissionCode == menuDto.Code)
                    {
                        hasMenu = true;
                        if (menuDto.BaseMenuButton.Count > 0)
                        {
                            for (int j = 0; j < menuDto.BaseMenuButton.Count; ++j)
                            {
                                BaseMenuButtonResultDto menuButtonDto = menuDto.BaseMenuButton.ElementAt(j);
                                bool hasMenuButton = false;
                                foreach (BaseRolePermissionDto item2 in rolePermissionDtos)
                                {
                                    if (item2.PermissionCode == menuButtonDto.MenuCode + menuButtonDto.Code)
                                    {
                                        hasMenuButton = true;
                                        break;
                                    }
                                }

                                if (!hasMenuButton)
                                {
                                    menuDto.BaseMenuButton.Remove(menuButtonDto);
                                    --j;
                                }
                            }
                        }
                        break;
                    }
                }

                if (!hasMenu)
                {
                    menuDtos.Remove(menuDto);
                    --i;
                }
            }
        }

        /// <summary>
        /// 头像更新
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public async Task<string> UploadPhoto([FromForm] IFormFile file)
        {
            return await _userService.UploadPhoto(file, YSession.SubjectId);
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseUserResultDto> PutChangePassword(ChangePasswordDto input)
        {
            input.Id = YSession.SubjectId;
            BaseUserResultDto userResultDto = await _userService.ChangePassword(input);
            return userResultDto;
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseUserResultDto> PutUpdateUser(BaseUserDto input)
        {
            BaseUserResultDto userResultDto = await _userService.EditUser(input);
            return userResultDto;
        }
    }
}